/*
 * Source: [[:pl:MediaWiki:Gadget-wikibugs.js]]
 * @author: [[:pl:User:Dodek]] (idea and text)
 * @author: [[:pl:User:Adziura]] (idea and text)
 * @author: [[:pl:User:Nux]] (implementation)
 * @author: [[:pl:User:Saper]] (implementation)
 * @author: [[:pl:User:Beau]] (implementation)
 * @author: [[:pt:User:ChristianH]] (Portuguese version)
 */
/* Translatable strings */
mw.messages.set( {
	'wikibugs-dialog-title': 'Informar um erro',
	'wikibugs-open-form-button': 'Informar',
	'wikibugs-edit-page-button': 'Editar a página e corrigir o erro',
	'wikibugs-cancel-button': 'Cancelar',
	'wikibugs-submit-report-button': 'Enviar',
	'wikibugs-ip-address-notice': '<b>Observação:</b> seu endereço de IP' +
		' ficará armazenado no histórico de notificações.',
	'wikibugs-page-name-label': 'Nome da página:<br/><small>(juntamente com' +
		' o prefixo "Imagem:" se estiver informando um erro em uma imagem ou' +
		' outro tipo de ficheiro/arquivo</small>',
	'wikibugs-report-content-label': 'Detalhes sobre o erro:<br><small>' +
		'<u>Não</u> deixe seu número de telefone, e-mail ou qualquer outro dado pessoal</small>',
	'wikibugs-report-content-placeholder': 'Explique aqui o problema detalhadamente e,' +
		' se possível, indique uma referência onde se possa confirmar a informação',
	'wikibugs-signature-label': 'Assinatura:',
	'wikibugs-edit-error': 'Ocorreu um erro ao enviar a notificação. Por favor, tente novamente.',
	'wikibugs-token-error': 'Ocorreu um erro ao solicitar um token por meio da API do MediaWiki: $1. $2.',	
	'wikibugs-unknown-token-error': 'Ocorreu um erro desconhecido ao solicitar um token por meio da API do MediaWiki.',
	'wikibugs-ajax-error': 'Houve um erro ao usar AJAX.',
	'wikibugs-incomplete-information': 'Descreva detalhadamente qual é o erro. Não coloque informações incompletas.',
	'wikibugs-invalid-page': 'Informe um nome válido para a página.',
	'wikibugs-reported-by': ' Enviado por: $1',
	'wikibugs-file-section-line': '<!-- Erros nas imagens a partir desta linha. Itens mais recentes no topo. -->',
	'wikibugs-page-section-line': '<!-- Erros nos artigos a partir desta linha. Itens mais recentes no topo. -->',
	'wikibugs-bad-reports-text': '<p>Neste formulário <b>não são aceitos</b> pedidos' +
		' para expandir ou criar artigos. Isso deve ser feito na página:</p>' +
		'<ul><li><a href="' + mw.util.wikiGetlink('Wikipédia:Artigos pedidos') +
		'">Artigos pedidos</a></li></ul><p><b>Não informe</b> erros em outros sites' +
		' (como <b>Facebook</b> ou <b>Twitter</b>), pois não serão atendidos.' +
		'<p>A Wikipédia não dá conselhos. Se precisa de aconselhamento,' +
		' <b>não peça aqui</b>.</p><p>Para informações sobre como contactar a Wikipédia,' +
		' consulte:</p><ul><li><a href="' + mw.util.wikiGetlink('Wikipédia:Contato') +
		'">Contato</a></li></ul>',
	'wikibugs-article-intro': '<p style="margin-top:0px;">É possível avisar' +
		' sobre erros encontrados nos artigos da Wikipédia, mas lembre-se de' +
		' que ela é uma <a href="' + mw.util.wikiGetlink('Wiki') +
		'">wíki</a> e por isso até mesmo o leitor pode <a href="' +
		mw.util.wikiGetlink('Wikipédia:Seja audaz') +
		'">ser audaz e corrigir um erro</a> encontrado durante a leitura.' +
		' No entanto, reconhecemos o fato de que alguns leitores da Wikipédia' +
		' têm motivos para não quererem editar e aprimorar os artigos diretamente.</p>' +
		'<p><b>Se puder corrigir o problema, não o informe aqui.</b></p>',
	'wikibugs-image-intro': '<p style="margin-top:0px;">Aqui é possível informar' +
		' sobre imagens que violam os termos da licença, que possuem versões' +
		' melhores no Wikimedia Commons, que estão descritas incorretamente etc. </p>' +
		'<p><b>Se puder corrigir o problema, não o informe aqui.</b></p>',
	'wikibugs-already-reported-notice': '<p><b>Observação:</b> se informou um problema' +
		' e agora ele já não existe, então provavelmente algum editor já o corrigiu.' +
		' Consulte:<ul><li><a href="' + mw.util.wikiGetlink('Wikipédia:Informe um erro') +
		'">a lista atual de problemas informados</a> e</li><li><a href="' +
		mw.util.wikiGetlink('Wikipédia:Informe um erro') +
		'?action=history">o histórico de modificações da página.</a></li></ul></p>',
	'wikibugs-footer': '<p>Leia os <a href="http://wikimediafoundation.org/wiki/' +
		'Condições_de_Uso" target="_blank">termos de uso</a> e a <a href="' +
		'http://wikimediafoundation.org/wiki/Política_de_privacidade"' +
		' target="_blank">política de privacidade</a> da Wikipédia.</p>',
	'wikibugs-new-report': 'Nova notificação: $1'
});
var wikiBugsGadget = {

	/**
	 * Version number of this gadget.
	 */
	version: 2,
	/**
	 * The page on which are written notification.
	 */
	reportPage: 'Wikipédia:Informe um erro',
	/**
	 * List of page titles which may not relate to the gadget.
	 */
	badPages: [
		'Wikipédia:Informe um erro'
	],
	/**
	 * Define pages where it's not needed or tends to encourage submission of large
	 * volumes of unrelated errors; instead, these load CSS which hides the "Report A Bug" link
	 */
	excludedPages: [
		// 'Wikipédia:Página principal'
	],
	/**
	 * Communication to the pages in the main space.
	 */
	articleIntro: '<div id="wbBadReports">' +
		mw.msg( 'wikibugs-bad-reports-text' ) + '</div>' +
		mw.msg( 'wikibugs-article-intro' ) +
		mw.msg( 'wikibugs-already-reported-notice' ) +
		mw.msg( 'wikibugs-footer' ),

	/**
	 * Message to the parties in the space of a file.
	 */
	imageIntro: '<div id="wbBadReports">' +
		mw.msg( 'wikibugs-bad-reports-text' ) + '</div>' +
		mw.msg( 'wikibugs-image-intro' ) +
		mw.msg( 'wikibugs-already-reported-notice' ) +
		mw.msg( 'wikibugs-footer' ),

	/**
	 * Function to check whether it should be accepted a report about the provided page.
	 * @param name Page name
	 */
	isValidPageName: function (name) {
		if (name === '') {
			return false;
		}
		if (name.indexOf( mw.config.get('wgFormattedNamespaces')[ '-1' ] ) === 0) {
			return false;
		}
		name = name.replace(/_/g, ' ');

		return $.inArray( name, this.badPages ) == -1;
	},

	/**
	 * This function initiates the action of the gadget.
	 */
	init: function() {
		var	excluded = false,
			$link, name, $articleBugLink, $imageBugLink,
			that = this;

		// Special pages and MediaWiki pages are excluded
		if ($.inArray( mw.config.get('wgNamespaceNumber'), [ -1 , 8 ]) > -1) {
			excluded = true;
		} else {
			name = mw.config.get('wgPageName').replace(/_/g, ' ');
			excluded = $.inArray( name, this.excludedPages ) != -1;
		}
		// FIXME: This doesn't exists on "standard", "cologneblue" (no ids) and "nostalgia" (no sidebar)
		$articleBugLink = $('#n-bug_in_article');
		$imageBugLink = $('#n-bad-image');
		that = this;

		if (excluded) {
			// hide the link
			if ($articleBugLink) {
				$articleBugLink.hide();
			}
			if ($imageBugLink) {
				$imageBugLink.hide();
			}
			return;
		}
		if ($articleBugLink) {
			$link = $articleBugLink.find('a')
				.attr( 'href', '#' )
				.click( function (event) {
					that.open(that.articleIntro);
					event.preventDefault();
				} );
		}
		if ($imageBugLink) {
			$link = $imageBugLink.find('a')
				.attr( 'href', '#' )
				.click( function (event) {
					that.open(that.imageIntro);
					event.preventDefault();
				} );
		}

		//link on the report-an-error page itself
		$('#report-bug-link a').click(function(event) {
			that.open(that.articleIntro);
			event.preventDefault();
		});
		importStylesheet('MediaWiki:Gadget-wikibugs.css');
	},
	/**
	 * Move to the edit page.
	 */
	goToEditPage: function() {
		var	$editLink = $( '#ca-edit' ).find( 'a' ),
			url = $editLink.attr( 'href' ) || mw.util.wikiGetlink( this.reportPage );
		window.location = url;
	},
	/**
	 * Loads the user interface.
	 * @param infoHtml Message content.
	 */
	open: function(infoHtml) {
		var that = this;

		mw.loader.using('jquery.ui.dialog', function() {
			that.openDialog(infoHtml);
		}); // FIXME: this should be loaded as gadget dependency
	},
	/**
	 * Shows the dialog.
	 * @param infoHtml Message content.
	 */
	openDialog: function(infoHtml) {
		var	that = this,
			edit_el = document.getElementById('ca-edit'),
			can_edit = edit_el ? true : false,
			$dialog = $('<div id="dialogContent"></div>').append(infoHtml);

		if (mw.user.anonymous()) {
			$dialog.append( '<p>' + mw.msg( 'wikibugs-ip-address-notice' ) + '</p>' );
		}

		var buttons = {};
		buttons[mw.msg( 'wikibugs-cancel-button' )] = function() {
			$(this).dialog('close');
		};
		buttons[mw.msg( 'wikibugs-open-form-button' )] = function() {
			that.openForm(this);
		};
		if (can_edit) {
			buttons[mw.msg( 'wikibugs-edit-page-button' )] = function() {
				that.goToEditPage();
			};
		}

		$dialog.dialog( {
			width: 700,
			height: 500,
			modal: true,
			resizable: false,
			draggable: true,
			closeOnEscape: true,
			dialogClass: 'reportBugDialog',
			title: mw.msg( 'wikibugs-dialog-title' ),
			close: function() {
				var $this = $(this);
				$this.dialog('destroy');
				$this.remove();
			},
			buttons: buttons
		});
		$('div.reportBugDialog button:last').focus();
	},
	/**
	 * Shows a window with the form.
	 */
	openForm: function(dialog) {
		var	that = this,
			buttons = {};
		$('#dialogContent').empty().append(
			'<form name="WikibugForm" enctype="multipart/form-data">' +
			'<fieldset>' +
			'<label for="wbPageTitle">' + mw.msg( 'wikibugs-page-name-label' ) + '</label>' +
			'<input id="wbPageTitle" type="text" name="wbPageTitle" class="text ui-widget-content ui-corner-all" />' +
			'<label for="wbText">' + mw.msg( 'wikibugs-report-content-label' ) + '</label>' +
			'<textarea id="wbText" name="wbText" rows="6" class="text ui-widget-content ui-corner-all">' +
			mw.msg( 'wikibugs-report-content-placeholder' ) + '</textarea>' +
			'<label for="wbAuthor">' + mw.msg( 'wikibugs-signature-label' ) + '</label>' +
			'<input id="wbAuthor" type="text" class="text ui-widget-content ui-corner-all"/>' +
			'</fieldset>' +
			'<img id="wikibugs-loading-icon" src="http://upload.wikimedia.org/wikipedia/commons/4/49/Linux_Ubuntu_Loader.gif" style="display:none;"/>'+
			'</form>'
		);

		buttons[mw.msg( 'wikibugs-cancel-button' )] = function() {
			$(this).dialog('close');
		};
		buttons[mw.msg( 'wikibugs-submit-report-button' )] = function() {
			that.submitForm();
		};

		$(dialog).dialog('option', 'buttons', buttons);

		$('#wbText').focus(function() {
			if (this.value == mw.msg( 'wikibugs-report-content-placeholder' )) {
				this.value = '';
			}
		});

		if (this.isValidPageName(mw.config.get('wgPageName'))) {
			$('#wbPageTitle').val( mw.config.get('wgPageName').replace(/_/g, ' ') );
		}

		if ( !mw.user.anonymous() ) {
			var author = document.getElementById('wbAuthor');
			author.value = '~~'+'~~';
			author.disabled = 'disabled';
		}
	},
	/**
	 * Sends the contents of the form.
	 */
	submitForm: function() {
		var	form = document.forms.WikibugForm,
			page = form.wbPageTitle.value,
			content = form.wbText.value,
			that = this;

		if (content == mw.msg( 'wikibugs-report-content-placeholder' )
			|| content.length < 20
			|| !content.match(' ')
		) {
			// Description too short or unchanged
			alert(mw.msg( 'wikibugs-incomplete-information' ));
			form.wbText.focus();
			return;
		}
		content = $.trim(content);

		var pageTitle; // Title of the reported page
		var isFile = false; // Is the reported page a file?

		// Signature
		if (!mw.user.anonymous()) {
			content += mw.msg( 'wikibugs-reported-by', '~~'+'~~' );
		} else {
			content += mw.msg( 'wikibugs-reported-by', form.wbAuthor.value + ' ~~'+'~~' );
		}
		if (page == mw.config.get('wgPageName') && this.isValidPageName(mw.config.get('wgPageName'))) {
			// User hasn't changed the page tilte - we're reporting the current page
			pageTitle = mw.config.get('wgPageName');
			page = page.replace(/_/g, ' ');
			page = '[[:' + pageTitle + '|' + page + ']]';

			isFile = (mw.config.get('wgNamespaceNumber') == 6);
		}
		else {
			// User has changed the page title - we're reporting the manually-specified page
			page = page.replace(/_/g, ' ');
			page = page.replace(/[\[\]\|]/g, '');
			page = $.trim(page);

			if (! this.isValidPageName(page) ) {
				alert( mw.msg( 'wikibugs-invalid-page' ) );
				if ( this.isValidPageName(mw.config.get('wgPageName')) ) {
					form.wbPageTitle.value = mw.config.get('wgPageName');
				} else {
					form.wbPageTitle.value = '';
					form.wbPageTitle.focus();
				}
				return;
			}

			pageTitle = page; // We're reporting the page specified manually by the user
			page = '[[:' + page + ']]';

			var fileNS = ['File:'];
			$.each(mw.config.get('wgNamespaceIds'), function(name,id){
				// Get a list of aliases for "File:" namespace
				if (id==6) {
					fileNS.push(
						$.escapeRE(
							name.charAt(0).toUpperCase() + name.substr(1)
						) + ':'
					);
				}
			});
			// Build a regex which match all aliases for "File:" namespace
			var reFile = new RegExp( '^(?:' + fileNS.join('|') + ')' );
			// Check if the user has typed a name of a file
			isFile = reFile.test( pageTitle );
		}

		form.submit.disabled = 'disabled';
		var loadingIcon = document.getElementById('wikibugs-loading-icon');
		loadingIcon.style.display = 'inline';

		var toInsert = '=== ' + page + ' ===\n' + content;

		function processContentOfPage( data ){
			var	query = data && data.query,
				pages = query && query.pages,
				pageids = query && query.pageids,
				sectionLine, firstPage, text;
			if (!pages || !pageids) {
				alert( mw.msg( 'wikibugs-edit-error' ) );
				return false;
			}
			firstPage = pages[ pageids[0] ];
			text = (firstPage && firstPage.revisions[0]['*']) || '';
			// Process the wikitext of the page
			if(isFile) {
				sectionLine = mw.msg( 'wikibugs-file-section-line' );
			} else {
				sectionLine = mw.msg( 'wikibugs-page-section-line' );
			}
			var newText = text.replace(sectionLine, sectionLine + '\n\n' + toInsert);
			if (text == newText) {
				// Could not find the section line - simply append;
				newText = text + '\n\n' + toInsert;
			}
			function afterEdit() {
				//saved successfully - go to the report page
				var reportPage = that.reportPage.replace(/ /g, '_');
				window.location = mw.util.wikiGetlink(reportPage) + '#' +
					encodeURIComponent(
						encodeURI(pageTitle).replace(/%/g, '.')
					).replace(/%/g, '.').replace(/\.3A/g, ':').
					replace(/\.20/g, '_').
					replace(/\(/g, '.28').replace(/\)/g, '.29');

				if (mw.config.get('wgPageName') == reportPage) {
					//we're already there
					window.location.reload();
				}
			}
			function doEditPage( token /*, starttimestamp*/ ) {
				$.ajax({
					url: mw.util.wikiScript( 'api' ),
					type: 'POST',
					dataType: 'json',
					data: {
						format: 'json',
						action: 'edit',
						title: that.reportPage,
						text: newText,
						minor: false,
						summary: mw.msg( 'wikibugs-new-report', page ),
						//starttimestamp: starttimestamp,
						token: token
					},
					success: afterEdit,
					error: function() {
						//handle the error
						alert( mw.msg( 'wikibugs-ajax-error' ) );
						form.submit.disabled = '';
						loadingIcon.style.display = 'none';
					}
				});
			}
			function getToken( data ){
				var pageInfo;
				if ( 'error' in data ) {
					alert( mw.msg( 'wikibugs-token-error', data.error.code, data.error.info ) );
					return false;
				} else if ( data.query && data.query.pages && data.query.pageids
					&& data.query.pages[ data.query.pageids[0] ]
				) {
					pageInfo = data.query.pages[ data.query.pageids[0] ];
					// Save the new content
					doEditPage( pageInfo.edittoken /*, pageInfo.starttimestamp*/ );
				} else {
					alert( mw.msg( 'wikibugs-unknown-token-error' ) );
					return false;
				}
			}
			// Get a token before editing
			$.ajax({
					url: mw.util.wikiScript( 'api' ),
					dataType: 'json',
					data: {
						format: 'json',
						action: 'query',
						prop: 'info',
						indexpageids: true,
						intoken: 'edit',
						titles: that.reportPage
					},
					success: getToken,
					error: function() {
						    alert( mw.msg( 'wikibugs-ajax-error' ) );
					}
			});
		}
		$.ajax({
			url: mw.util.wikiScript( 'api' ),
			dataType: 'json',
			data: {
				'format': 'json',
				'action': 'query',
				'titles': that.reportPage,
				'prop': 'revisions',
				'rvprop': 'content',
				'indexpageids': true
			},
			success: processContentOfPage,
			error: function() {
					alert( mw.msg( 'wikibugs-ajax-error' ) );
			}
		});
	}
};

$(function() {
	wikiBugsGadget.init();
});